package jukebox.controller;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import jukebox.model.common.CommentVO;
import jukebox.model.member.MemberVO;
import jukebox.model.musicboard.MusicBoardService;
import jukebox.model.musicboard.MusicBoardVO;

import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MusicBoardController {
	@Resource(name="musicBoardServiceImpl")
	private MusicBoardService musicboardService;
	
	private String absPath = "";		// 저장소 root 절대 경로
	private String audioPath = "";		// 음원 저장 상대 경로
	private String albumartPath = ""; 	// 앨범아트 저장 상대 경로
	
	/**
	 * @method : MusicBoardController
	 * @author : 김준섭
	 * @since : 2014-06-25
	 * @param : ServletContext context - 경로 정보를 가져오기 위한 ServletContext
	 * @comment : 경로 정보를 초기화하기 위한 생성자
	 */
	@Autowired
	public MusicBoardController(ServletContext context){
		absPath = context.getInitParameter("absPath");
		String[] temp = context.getInitParameter("audioPath").split("/");
		for(int i=0; i<temp.length; i++){
			audioPath += temp[i] + "\\";
		}
		temp = context.getInitParameter("albumartPath").split("/");
		for(int i=0; i<temp.length; i++){
			albumartPath += temp[i] + "\\";
		}
	}

	/**
	 * @method : fileDelete
	 * @author : 김준섭
	 * @since : 2014-06-25
	 * @param : String filename - 삭제될 파일 경로
	 * @return : void
	 * @comment : 파일을 삭제하기 위한 함수
	 */
	private void fileDelete(String filename){
		if(filename!=null){
			File file = new File(filename);
			file.delete();
		}
	}
	
	/**
	 * @method : fileDownload
	 * @author : 김준섭
	 * @since : 2014-06-25
	 * @param : MusicBoardVO mbvo - 검색 정보를 담은 객체
	 * @comment : 게시판의 파일을 다운로드하기 위한 함수 
	 */
	@RequestMapping("fileDownload.ju")
	public ModelAndView fileDownload(MusicBoardVO mbvo){
		HashMap map = new HashMap();
		map.put("path", absPath+audioPath);
		
		return new ModelAndView("downloadView", map);
	}
	
	/**
	 * @method : pagingContent
	 * @author : 김준섭
	 * @since : 2014-06-23
	 * @param : MusicBoardVO mbvo - 검색 정보를 담은 객체
	 * @comment : 검색된 한 페이지에 해당하는 게시물 리스트를 받아오기 위한 함수 
	 */
	@RequestMapping("musicboard_pagingContent.ju")
	public ModelAndView pagingContent(MusicBoardVO mbvo, int nowPage){
		return new ModelAndView("home", "listVO", musicboardService.pagingContent(mbvo));
	}
	
	/**
	 * @method : morePagingContent
	 * @author : 김준섭
	 * @since : 2014-06-23
	 * @param : MusicBoardVO mbvo - 검색 정보를 담은 객체
	 * 				int nowPage - 페이징 번호
	 * @comment : 검색된 추가 페이지에 해당하는 게시물 리스트를 받아오기 위한 함수 
	 */
	@RequestMapping(value="musicboard_morePagingContent.ju", method=RequestMethod.POST)
	@ResponseBody
	public Object morePagingContent(MusicBoardVO mbvo, int nowPage){
		return musicboardService.pagingMoreContent(mbvo, nowPage);
	}
	
	/**
	 * @method : goWriteContent
	 * @author : 김준섭
	 * @since : 2014-06-24
	 * @comment : 글쓰기 페이지로 이동하기 위한 함수 
	 */
	@RequestMapping("musicboard_goWriteContent.ju")
	public String goWriteContent(){
		return "write.musicboard";
	}
	
	/**
	 * @method : writeContent
	 * @author : 김준섭
	 * @since : 2014-06-24
	 * @param : MusicBoardVO mbvo - 등록될 음악게시물 정보
	 * @comment : 음악게시물을 등록하기 위한 함수 
	 * 					파일도 생성한다.
	 */
	@RequestMapping("musicboard_writeContent.ju")
	public String writeContent(MusicBoardVO mbvo, HttpSession session){
		MultipartFile mFile = mbvo.getUploadFile();
		MultipartFile mPictureFile = mbvo.getUploadPictureFile();
		
		if(mFile!=null&&!mFile.isEmpty()){
			// 음악파일 복사
			String newFileName = System.currentTimeMillis()+"_"+mFile.getOriginalFilename();
			mbvo.setOrgFile(mFile.getOriginalFilename());
			mbvo.setNewFile(newFileName);				// 시간 붙여서 음악파일명 저장
			File copyFile = new File(absPath+audioPath+newFileName);
			// 이미지파일 복사
			File copyPictureFile = null;
			if(mPictureFile!=null&&!mPictureFile.isEmpty()){
				String newPictureFileName = System.currentTimeMillis()+"_"+mPictureFile.getOriginalFilename();
				mbvo.setPictureFile(newPictureFileName);	// 시간 붙여서 이미지파일명 저장
				copyPictureFile = new File(absPath+albumartPath+newPictureFileName);
			}
			
			try {
				musicboardService.writeContent(mbvo);
				if(copyFile!=null)mFile.transferTo(copyFile);						// 실제 디렉토리로 음악파일을 저장한다.
				if(copyPictureFile!=null)mPictureFile.transferTo(copyPictureFile);		// 실제 디렉토리로 이미지파일을 저장한다.
			} catch (IllegalStateException | IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return "redirect:musicboard_findContentByNo.ju?boardNo="+mbvo.getNo();
	}
	
	/**
	 * @method : goUpdateContent
	 * @author : 김준섭
	 * @since : 2014-06-25
	 * @comment : 수정 페이지로 이동하기 위한 함수 
	 */
	@RequestMapping("musicboard_goUpdateContent.ju")
	public ModelAndView goUpdateContent(int no){
		return new ModelAndView("update.musicboard", "mbvo", musicboardService.findContentByNo(no));
	}
	
	/**
	 * @method : updateContent
	 * @author : 김준섭
	 * @since : 2014-06-25
	 * @param : MusicBoardVO mbvo - 수정될 음악게시물 정보
	 * @comment : 음악게시물을 수정하기 위한 함수 
	 * 					파일이 변경되면 기존 파일 삭제후 
	 * 					변경된 파일을 생성한다.
	 */
	@RequestMapping("musicboard_updateContent.ju")
	public String updateContent(MusicBoardVO mbvo){
		MultipartFile mFile = null;
		MultipartFile mPictureFile = null;
		// 수정할 음악파일이 존재하면
		if(mbvo.getUploadFile() != null && !mbvo.getUploadFile().isEmpty()){
			fileDelete(absPath+audioPath+mbvo.getNewFile());
			mFile = mbvo.getUploadFile();
		}
		// 수정할 앨범아트파일이 존재하면
		if(mbvo.getUploadPictureFile() != null && !mbvo.getUploadPictureFile().isEmpty()){
			if(!mbvo.getPictureFile().equals("no_albumart.png"))
				fileDelete(absPath+albumartPath+mbvo.getPictureFile());
			mPictureFile = mbvo.getUploadPictureFile();
		}
		
		// 앨범파일 삭제
		if(mbvo.getPictureFile().endsWith(".del")){
			String albumartName = mbvo.getPictureFile().substring(0, mbvo.getPictureFile().lastIndexOf(".del"));
			if(!albumartName.equals("no_albumart.png"))
				fileDelete(absPath+albumartPath+albumartName);
			mbvo.setPictureFile("no_albumart.png");
		}
		
		File copyFile = null;
		File copyPictureFile = null;
		if(mFile!=null&&!mFile.isEmpty()){
			// 음악파일 복사
			String newFileName = System.currentTimeMillis()+"_"+mFile.getOriginalFilename();
			mbvo.setOrgFile(mFile.getOriginalFilename());
			mbvo.setNewFile(newFileName);				// 시간 붙여서 음악파일명 저장
			copyFile = new File(absPath+audioPath+newFileName);
		}
		// 이미지파일 복사
		if(mPictureFile!=null&&!mPictureFile.isEmpty()){
			String newPictureFileName = System.currentTimeMillis()+"_"+mPictureFile.getOriginalFilename();
			mbvo.setPictureFile(newPictureFileName);	// 시간 붙여서 이미지파일명 저장
			copyPictureFile = new File(absPath+albumartPath+newPictureFileName);
		}
		try {
			musicboardService.updateContent(mbvo);
			if(copyFile!=null)mFile.transferTo(copyFile);								// 실제 디렉토리로 음악파일을 저장한다.
			if(copyPictureFile!=null)mPictureFile.transferTo(copyPictureFile);		// 실제 디렉토리로 이미지파일을 저장한다.
		} catch (IllegalStateException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return "redirect:musicboard_findContentByNo.ju?boardNo="+mbvo.getNo();
	}
	
	/**
	 * @method : deleteContent
	 * @author : 김준섭
	 * @since : 2014-06-25
	 * @param : int no - 삭제될 음악게시물 번호
	 * @comment : 음악게시물을 삭제하기 위한 함수 
	 * 					게시물에 해당하는 파일들도 삭제
	 */
	@RequestMapping("musicboard_deleteContent.ju")
	public String deleteContent(HttpServletRequest request, int no){
		MusicBoardVO mbvo = musicboardService.findContentByNo(no);
		musicboardService.deleteContent(no);
		
		fileDelete(absPath+audioPath+mbvo.getNewFile());
		if(!mbvo.getPictureFile().equals("no_albumart.png"))
			fileDelete(absPath+albumartPath+mbvo.getPictureFile());

		return "redirect:musicboard_pagingContent.ju?nowPage=1";
	}
	
	/**
	 * @method : findContentByNo
	 * @author : 김준섭
	 * @since : 2014-06-24
	 * @param : int boardNo - 검색할 게시물 번호
	 * @comment : 상세 게시물 정보를 검색하기 위한 함수
	 */
	@RequestMapping("musicboard_findContentByNo.ju")
	public ModelAndView findContentByNo(int boardNo){
		return new ModelAndView("detail.musicboard", "mbvo", musicboardService.findContentByNo(boardNo));
	}

	/**
	 * @method : updateLike
	 * @author : 김준섭
	 * @since : 2014-06-27
	 * @param :  String cookieValue - 추천된 게시물의 정보를 담고있는 쿠키값
	 * 				int boardNo - 추천될 게시물 번호
	 * @comment : 게시물을 추천하기 위한 함수
	 * 					쿠키값을 검색하여 해당 게시물이 추천되지않았으면 추천을 한다.
	 */
	@RequestMapping("musicboard_updateLike.ju")
	@ResponseBody
	public Map updateLike(@CookieValue(value="musicboardLike", required=false) String cookieValue, HttpServletResponse response, int boardNo) throws JSONException{
		JSONObject obj = new JSONObject();
		Date date = new Date();
		String no = ""+boardNo;

		int result = 0;
		Map map = new HashMap<>();
		String msg = "이미 추천을 하였습니다.";
		
		if(cookieValue!=null){	// 글번호 쿠키가 있으면
			obj = new JSONObject(cookieValue);
			
			if(obj.isNull(no)){	// 해당 글번호 정보가 없으면
				obj.put(no, date.toString());
				result = musicboardService.updateLike(boardNo);
			}
			Cookie cookie = new Cookie("musicboardLike", obj.toString());
			cookie.setMaxAge(24*60*60);
			response.addCookie(cookie);
		}else{	// 글번호 쿠기가 없으면
			obj.put(no, date.toString());
			result = musicboardService.updateLike(boardNo);
			Cookie cookie = new Cookie("musicboardLike", obj.toString());
			cookie.setMaxAge(24*60*60);
			response.addCookie(cookie);
		}
		
		if(result > 0){
			msg = "추천을 하였습니다.";
		}
		int likeCnt = musicboardService.findContentByNo(boardNo).getLike();
		
		map.put("msg", msg);
		map.put("likeCnt", likeCnt);
		
		return map;
	}
	
	/**
	 * @method : updateHit
	 * @author : 김준섭
	 * @since : 2014-06-27
	 * @param :  String cookieValue - 조회된 게시물의 정보를 담고있는 쿠키값
	 * 				int boardNo - 조회수가 증가될 게시물 번호
	 * @comment : 게시물의 조회수를 증가하기 위한 함수
	 * 					쿠키값을 검색하여 해당 게시물이 조회되지않았으면 조회수를 증가 한다.
	 */
	@RequestMapping("musicboard_updateHit.ju")
	public String updateHit(@CookieValue(value="musicboardCount", required=false) String cookieValue, HttpServletResponse response, int boardNo) throws JSONException{
		// 쿠키검사해서
		// 카운팅한당!
		JSONObject obj = new JSONObject();
		Date date = new Date();
		String no = ""+boardNo;
		
		if(cookieValue!=null){	// 글번호 쿠키가 있으면
			obj = new JSONObject(cookieValue);
			
			if(obj.isNull(no)){	// 해당 글번호 정보가 없으면
				obj.put(no, date.toString());
				musicboardService.updateHit(boardNo);
			}
			response.addCookie(new Cookie("musicboardCount", obj.toString()));
		}else{	// 글번호 쿠기가 없으면
			obj.put(no, date.toString());
			musicboardService.updateHit(boardNo);
			response.addCookie(new Cookie("musicboardCount", obj.toString()));
		}
		return "redirect:musicboard_findContentByNo.ju?boardNo="+no;
	}
	
	//게시글 추천 수 기준의 랭킹
	// head가 갱신될떄마다 ajax로 갱신 $(docu).ready
	@RequestMapping("musicboard_getRankListByLike.ju")
	@ResponseBody
	public List getRankListByLike(){
		return musicboardService.getRankListByLike();
	}
	
	/////////// 댓글 ///////////////
	/**
	 * @method : pagingComment
	 * @author : 김준섭
	 * @since : 2014-06-23
	 * @param : int boardNo - 댓글을 검색할 게시물 번호
	 * 				int nowPage - 댓글의 페이징 번호
	 * @return : Object - 페이지의 정보를 담은 Map
	 * 						페이지 정보를 담은 pagingBean
	 * 						게시물 번호를 담은 boardNo
	 * 						한 페이지의 댓글 리스트를 담은 list
	 * @comment : 검색된 한 페이지에 해당하는 댓글 리스트를 받아오기 위한 함수 
	 */
	@RequestMapping("musicboard_pagingComment.ju")
	@ResponseBody
	public Object pagingComment(int boardNo, int nowPage){
		return musicboardService.pagingComment(boardNo, nowPage);
	}
	
	/**
	 * @method : writeComment
	 * @author : 김준섭
	 * @since : 2014-06-26
	 * @param : CommentVO mcvo - 등록할 음악 댓글의 정보
	 * 				int boardNo - 댓글이 등록될 게시물 번호
	 * @comment : 음악게시물의 댓글 추가하기 위한 함수 
	 */
	@RequestMapping("musicboard_writeComment.ju")
	public String writeComment(CommentVO mcvo){
		musicboardService.writeComment(mcvo);
		return "redirect:musicboard_findCommentListByBoardNo.ju?boardNo="+mcvo.getBoardNo();
	}
	
	/**
	 * @method : updateComment
	 * @author : 김준섭
	 * @since : 2014-06-26
	 * @param : CommentVO mcvo - 수정될 음악 댓글 정보
	 * @comment : 음악 댓글을 수정하기 위한 함수 
	 */
	@RequestMapping("musicboard_updateComment.ju")
	public String updateComment(CommentVO mcvo){
		musicboardService.updateComment(mcvo);
		return "redirect:musicboard_findCommentByCommentNo.ju?boardNo="+mcvo.getNo();
	}
	
	/**
	 * @method : deleteComment
	 * @author : 김준섭
	 * @since : 2014-06-26
	 * @param : int no - 삭제될 음악 댓글 번호
	 * 				int boardNo - 게시물 번호
	 * @comment : 음악 댓글을 삭제하기 위한 함수 
	 */
	@RequestMapping("musicboard_deleteComment.ju")
	public String deleteComment(int no, int boardNo){
		musicboardService.deleteComment(no);
		return "redirect:musicboard_pagingComment.ju?nowPage=1&boardNo="+boardNo;
	}
	
	/**
	 * @method : findCommentListByBoardNo
	 * @author : 김준섭
	 * @since : 2014-06-26
	 * @param : int boardNo - 게시물 번호
	 * @return : List - 게시물의 전체 댓글 정보
	 * @comment : 게시물에 해당하는 전체 댓글을 검색하기 위한 함수
	 */
	@RequestMapping("musicboard_findCommentListByBoardNo.ju")
	@ResponseBody
	public List findCommentListByBoardNo(int boardNo){
		return musicboardService.findCommentListByBoardNo(boardNo);
	}
	
	/**
	 * @method : findCommentByCommentNo
	 * @author : 김준섭
	 * @since : 2014-06-26
	 * @param : int boardNo - 검색할 댓글 번호
	 * @return : Object - 댓글 정보
	 * @comment : 댓글 번호를 검색하여 댓글 정보를 가져오기 위한 함수
	 */
	@RequestMapping("musicboard_findCommentByCommentNo.ju")
	@ResponseBody
	public Object findCommentByCommentNo(int boardNo){
		return musicboardService.findCommentByCommentNo(boardNo);
	}
}
